package com.ruoyi.param.controller;

import com.ruoyi.base.service.IRoomService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.iot.IotContext;
import com.ruoyi.iot.WebTasksCallBack;
import com.ruoyi.iot.client.NioClient;
import com.ruoyi.iot.domain.CjqMeter;
import com.ruoyi.iot.domain.MeterCallStatus;
import com.ruoyi.iot.domain.vo.MeterCallStatusVo;
import com.ruoyi.param.domain.TparamTm;
import com.ruoyi.param.service.ITparamTmService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;

@RestController
@RequestMapping("/param/tm")
@Api(tags = "时间参数")
public class TparamTmController extends BaseController {

    @Value("${iot.webTimeOut}")
    private long webTimeOut;

    @Autowired
    private IRoomService roomService;

    @Autowired
    private ITparamTmService tParamTmService;

    @Autowired
    private IotContext iotContext;

    /**
     * 查询时间参数列表
     */
    @GetMapping("/list")
    @ApiOperation("查询时间参数列表")
    public TableDataInfo<TparamTm> list(TparamTm tparamTm) {
        startPage();
        List<TparamTm> list = tParamTmService.selectTmList(tparamTm);
        return getDataTable(list);
    }

    /**
     * 查看
     */
    @GetMapping("/view")
    @ApiOperation("查看")
    public TableDataInfo<TparamTm> view(String roomId) {
        startPage();
        List<TparamTm> list = tParamTmService.selectByRoomId(roomId);
        return getDataTable(list);
    }

    /**
     * 校时
     */
    @PreAuthorize("@ss.hasPermi('param:tm:set')")
    @GetMapping("/set")
    @ApiOperation("校时")
    public DeferredResult<AjaxResult> set(@RequestParam("roomIds") List<String> roomIds) {

        List<MeterCallStatus> meterCallStatusList = new CopyOnWriteArrayList<>();
        MeterCallStatusVo meterCallStatusVo = new MeterCallStatusVo().setStatusList(meterCallStatusList);
        final DeferredResult<AjaxResult> deferredResult = new DeferredResult<>(webTimeOut);
        deferredResult.onTimeout(() -> deferredResult.setResult(AjaxResult.success(meterCallStatusVo)));

        List<CjqMeter> cjqMeterList = roomService.selectCjqMeterList(roomIds);
        if (cjqMeterList.isEmpty()) {
            deferredResult.setResult(AjaxResult.success(meterCallStatusVo));
        }
        CountDownLatch countDownLatch = new CountDownLatch(roomIds.size());
        for (CjqMeter cjqMeter : cjqMeterList) {

            MeterCallStatus meterCallStatus = new MeterCallStatus().setRoomId(cjqMeter.getRoomId()).setStatus(1);
            meterCallStatusList.add(meterCallStatus);

            NioClient nioClient = iotContext.getNioClientMap().get(cjqMeter.getCjqNo());
            if (nioClient != null) {
                nioClient.writeProofreadTime(Integer.valueOf(cjqMeter.getMeterNo()).byteValue(), new WebTasksCallBack(cjqMeter.getRoomId()) {
                    @Override
                    public void callBack(boolean res) {
                        meterCallStatus.setStatus(res ? 0 : 1);
                        countDownLatch.countDown();
                        if (countDownLatch.getCount() == 0) {
                            deferredResult.setResult(AjaxResult.success(meterCallStatusVo));
                        }
                    }
                }.setTParamTmService(tParamTmService));
            } else {
                countDownLatch.countDown();
            }
            if (countDownLatch.getCount() == 0) {
                deferredResult.setResult(AjaxResult.success(meterCallStatusVo));
            }
            roomIds.remove(cjqMeter.getRoomId());
        }

        for (String roomId : roomIds) {
            MeterCallStatus meterCallStatus = new MeterCallStatus().setRoomId(roomId).setStatus(1);
            meterCallStatusList.add(meterCallStatus);
            countDownLatch.countDown();
            if (countDownLatch.getCount() == 0) {
                deferredResult.setResult(AjaxResult.success(meterCallStatusVo));
            }
        }
        return deferredResult;
    }

    /**
     * 召测时间参数
     */
    @PreAuthorize("@ss.hasPermi('param:tm:call')")
    @GetMapping("/call")
    @ApiOperation("召测时间参数")
    public DeferredResult<AjaxResult> call(@RequestParam("roomIds") List<String> roomIds) {

        List<MeterCallStatus> meterCallStatusList = new CopyOnWriteArrayList<>();
        MeterCallStatusVo meterCallStatusVo = new MeterCallStatusVo().setStatusList(meterCallStatusList);
        final DeferredResult<AjaxResult> deferredResult = new DeferredResult<>(webTimeOut);
        deferredResult.onTimeout(() -> deferredResult.setResult(AjaxResult.success(meterCallStatusVo)));

        List<CjqMeter> cjqMeterList = roomService.selectCjqMeterList(roomIds);
        if (cjqMeterList.isEmpty()) {
            deferredResult.setResult(AjaxResult.success(meterCallStatusVo));
        }
        CountDownLatch countDownLatch = new CountDownLatch(roomIds.size());
        for (CjqMeter cjqMeter : cjqMeterList) {

            MeterCallStatus meterCallStatus = new MeterCallStatus().setRoomId(cjqMeter.getRoomId()).setStatus(1);
            meterCallStatusList.add(meterCallStatus);

            NioClient nioClient = iotContext.getNioClientMap().get(cjqMeter.getCjqNo());
            if (nioClient != null) {
                nioClient.readProofreadTime(Integer.valueOf(cjqMeter.getMeterNo()).byteValue(), new WebTasksCallBack(cjqMeter.getRoomId()) {
                    @Override
                    public void callBack(boolean res) {
                        meterCallStatus.setStatus(res ? 0 : 1);
                        countDownLatch.countDown();
                        if (countDownLatch.getCount() == 0) {
                            deferredResult.setResult(AjaxResult.success(meterCallStatusVo));
                        }
                    }
                }.setTParamTmService(tParamTmService));
            } else {
                countDownLatch.countDown();
            }
            if (countDownLatch.getCount() == 0) {
                deferredResult.setResult(AjaxResult.success(meterCallStatusVo));
            }
            roomIds.remove(cjqMeter.getRoomId());
        }

        for (String roomId : roomIds) {
            MeterCallStatus meterCallStatus = new MeterCallStatus().setRoomId(roomId).setStatus(1);
            meterCallStatusList.add(meterCallStatus);
            countDownLatch.countDown();
            if (countDownLatch.getCount() == 0) {
                deferredResult.setResult(AjaxResult.success(meterCallStatusVo));
            }
        }
        return deferredResult;
    }

    /**
     * 删除时间参数
     */
    @PreAuthorize("@ss.hasPermi('param:tm:del')")
    @GetMapping("/del")
    @ApiOperation("删除时间参数")
    public AjaxResult del(@RequestParam("roomIds") List<String> roomIds) {
        tParamTmService.deleteByRoomIds(roomIds);
        return AjaxResult.success();
    }
}
